/*
-----------------------------------------------------------------------------
This file is part of NxGraphics, Multimedia Engine.
Author : Stephane Kyles. Developed in Prague, Czech Republic.
		_   __       ______                     __     _            
	   / | / /_  __ / ____/_____ ____ _ ____   / /_   (_)_____ _____
	  /  |/ /| |/_// / __ / ___// __ `// __ \ / __ \ / // ___// ___/
	 / /|  /_>  < / /_/ // /   / /_/ // /_/ // / / // // /__ (__  ) 
	/_/ |_//_/|_| \____//_/    \__,_// .___//_/ /_//_/ \___//____/  
									/_/                             
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-----------------------------------------------------------------------------
*/
#ifndef __NXGRAPHICSSERIALIZER_H__
#define __NXGRAPHICSSERIALIZER_H__

#include "NxGraphics_Prerequisites.h"

class TiXmlDocument;
class TiXmlDocument; 
class TiXmlElement;

namespace NxGraphics_Namespace {

//! Deserializer Class.
class NxGraphics_Export NxGraphicsDeSerializer 
{
public :
	//! NxGraphicsDeSerializer Class Constructor.
	NxGraphicsDeSerializer();
	//! NxGraphicsDeSerializer Class Deconstructor.
	~NxGraphicsDeSerializer();
	//! Get Root Element Name.
	void GetRootElementName( std::string & RootName );
	//! Start Parsing an Attribute.
	void beginAttribute( const std::string& name );
	//! Start Parsing an Attribute with given index.
	void beginAttribute( int index );
	//! End Parsing an Attribute.
	void endAttribute();
	//! Get Child Name
	void GetChildName(  std::string& ChildAttributeName, int ChildIndex );
	//! Get number of attributes.
	unsigned int ReadNumberOfElements();
	//! Read Attribute or node value.
	void ReadParameter( const std::string& name, std::string& value, bool AttributeValue = true );
	//! Read Attribute or node value.
	void ReadParameter( const std::string& name, bool& value, bool AttributeValue = true );  
	//! Read Attribute or node value.
	void ReadParameter( const std::string& name, short& value, bool AttributeValue = true );  
	//! Read Attribute or node value.	
	void ReadParameter( const std::string& name, int& value, bool AttributeValue = true );  
	//! Read Attribute or node value.	
	void ReadParameter( const std::string& name, long& value, bool AttributeValue = true );
	//! Read Attribute or node value.	
	void ReadParameter( const std::string& name, unsigned long& value, bool AttributeValue = true );  
	//! Read Attribute or node value.	
	void ReadParameter( const std::string& name, float& value, bool AttributeValue = true );  
	//! Read Attribute or node value.	
	void ReadParameter( const std::string& name, double& value, bool AttributeValue = true );  
	//! Read Attribute or node value.	
	void ReadParameter( const std::string& name, Ogre::Vector4& value, bool AttributeValue = true );
	//! Read Attribute or node value.	
	void ReadParameter( const std::string& name, Ogre::Vector3& value, const std::string & Split = " ", bool AttributeValue = true );
	//! Read Attribute or node value.	
	void ReadParameter( const std::string& name, Ogre::Vector2& value, bool AttributeValue = true );
	//! Open Xml File;
	bool open( std::string pFilename );
	//! Parse Xml string Nodes.
	void Parse( const std::string & Text );
	//! Get Xml Document.
	TiXmlDocument * GetDocument(){ return doc; }  
	protected:  
	//! get Node Value
	const std::string getChildValue( const std::string & NodeName );
	//! Get Attribute Value;
	const std::string getValue( const std::string& name ); 
	//! The actual XML document created by the serializer.
	TiXmlDocument * doc; 
	//! The current node we're working on.
	TiXmlElement* currentElement; 

};

//! Serializer Class.
class NxGraphics_Export NxGraphicsSerializer 
{
public :
	//! NxGraphicsSerializer Class Constructor.
	NxGraphicsSerializer();
	//! NxGraphicsSerializer Class Deconstructor.
	~NxGraphicsSerializer();
	void beginAttribute( const std::string& name );  
	void endAttribute();  
	void writeNumberOfElements( __int32 numElements ){ } // Not used for XML  
	void writeParameter( const std::string& name, const std::string& value );  
	void writeParameter( const std::string& name, const bool& value );  
	void writeParameter( const std::string& name, const short& value );  
	void writeParameter( const std::string& name, const int& value );  
	void writeParameter( const std::string& name, const long& value );  
	void writeParameter( const std::string& name, const unsigned long& value );  
	void writeParameter( const std::string& name, const float& value );  
	void writeParameter( const std::string& name, const double& value ); 
	void writeParameter( const std::string& name, const Ogre::Vector4& value );
	void writeParameter( const std::string& name, const Ogre::Vector3& value );
	void writeParameter( const std::string& name, const Ogre::Vector2& value );
	bool save( std::string pFilename );
	TiXmlDocument *  GetDocument(){ return doc; }  
	protected:  
	//! The actual XML document created by the serializer.
	TiXmlDocument * doc;
	//! The current node we're working on.
	TiXmlElement* currentElement; 

};

class NxGraphics_Export NxGraphicsConfiguration 
{
public:
	NxGraphicsConfiguration(){};
	explicit NxGraphicsConfiguration( const std::string& );
	explicit NxGraphicsConfiguration( double );
	explicit NxGraphicsConfiguration( const char* );
	NxGraphicsConfiguration( const NxGraphicsConfiguration& );
	NxGraphicsConfiguration& operator=( NxGraphicsConfiguration const& );
	NxGraphicsConfiguration& operator=( double );
	NxGraphicsConfiguration& operator=( std::string const& );
public:
	operator std::string() const;
	operator double     () const;
private:
	std::string value_;
};

class NxGraphics_Export NxConfigFile 
{
	std::map<std::string,NxGraphicsConfiguration> content_;
public:
	NxConfigFile(std::string const& configFile);
	NxGraphicsConfiguration const& Value(std::string const& section, std::string const& entry) const;
	NxGraphicsConfiguration const& Value(std::string const& section, std::string const& entry, double value);
	NxGraphicsConfiguration const& Value(std::string const& section, std::string const& entry, std::string const& value);
};

}  
#endif